<!DOCTYPE html>
<html lang="en">

<head>
  <base href="https://git-scm.com/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E5%B1%9E%E6%80%A7" />
  <meta charset='utf-8'>
  <meta content='IE=edge,chrome=1' http-equiv='X-UA-Compatible'>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Git - Git 属性</title>

  <link href='/favicon.ico' rel='shortcut icon' type='image/x-icon'>

  <link rel="stylesheet" media="screen" href="/assets/application-a058ab010d6f86a86903175bbfdaac30ef6057e5901875616753328abbf98b2c.css" />
  <script src="/assets/modernize-b3ebe0c31c24f230dc62179d3e1030d2e57a53b1668d9382c0a27dbd44a94beb.js"></script>
  <!--[if (gte IE 6)&(lte IE 8)]>
  <script src="/javascripts/selectivizr-min.js"></script>
  <![endif]-->

</head>

<body id="documentation">

  <div class="inner">
    <header>

  <a href="/"><img src="/images/logo@2x.png" width="110" height="46" alt="Git" /></a>
  <span id="tagline"></span>
  <script type="text/javascript">
    var taglines = ["fast-version-control","everything-is-local","distributed-even-if-your-workflow-isnt","local-branching-on-the-cheap","distributed-is-the-new-centralized"];
    var tagline = taglines[Math.floor(Math.random() * taglines.length)];
    document.getElementById('tagline').innerHTML = '--' + tagline;
  </script>
  <form id="search" action="/search/results">
    <input id="search-text" name="search" placeholder="Search entire site..." autocomplete="off" type="text" />
  </form>
  <div id="search-results"></div>

</header>

  </div> <!-- .inner -->

    <div class="inner">
      <div id="content-wrapper">
        <button class="sidebar-btn"></button>
<aside class="sidebar" id="sidebar">
  <nav>
    <ul>
      <li>
        <a href="/about">About</a>
        <ul class="">
          <li>
            <a href="/about">Branching and Merging</a>
          </li>
          <li>
            <a href="/about/small-and-fast">Small and Fast</a>
          </li>
          <li>
            <a href="/about/distributed">Distributed</a>
          </li>
          <li>
            <a href="/about/info-assurance">Data Assurance</a>
          </li>
          <li>
            <a href="/about/staging-area">Staging Area</a>
          </li>
          <li>
            <a href="/about/free-and-open-source">Free and Open Source</a>
          </li>
          <li>
            <a href="/about/trademark">Trademark</a>
          </li>
        </ul>
      </li>
      <li>
        <a class="active" href="/doc">Documentation</a>
        <ul class="expanded">
          <li>
            <a href="/docs">Reference</a>
          </li>
          <li>
            <a class="active" href="/book">Book</a>
          </li>
          <li>
            <a href="/videos">Videos</a>
          </li>
          <li>
            <a href="/doc/ext">External Links</a>
          </li>
        </ul>
      </li>
      <li>
        <a href="/downloads">Downloads</a>
        <ul class="">
          <li>
            <a href="/downloads/guis">GUI Clients</a>
          </li>
          <li>
            <a href="/downloads/logos">Logos</a>
          </li>
        </ul>
      </li>
      <li>
        <a href="/community">Community</a>
      </li>
    </ul>
      <hr class="sidebar">
        <p>
This book is available in
  <a href="/book/en">English</a>.
</p>
<p>
  Full translation available in
  <table>
    <tr><td><a href="/book/az">azərbaycan dili</a>,</td></tr>
    <tr><td><a href="/book/bg">български език</a>,</td></tr>
    <tr><td><a href="/book/de">Deutsch</a>,</td></tr>
    <tr><td><a href="/book/es">Español</a>,</td></tr>
    <tr><td><a href="/book/fr">Français</a>,</td></tr>
    <tr><td><a href="/book/gr">Ελληνικά</a>,</td></tr>
    <tr><td><a href="/book/ja">日本語</a>,</td></tr>
    <tr><td><a href="/book/ko">한국어</a>,</td></tr>
    <tr><td><a href="/book/nl">Nederlands</a>,</td></tr>
    <tr><td><a href="/book/ru">Русский</a>,</td></tr>
    <tr><td><a href="/book/sl">Slovenščina</a>,</td></tr>
    <tr><td><a href="/book/tl">Tagalog</a>,</td></tr>
    <tr><td><a href="/book/uk">Українська</a></td></tr>
    <tr><td><a href="/book/zh">简体中文</a>,</td></tr>
  </table>
</p>
<p>
  Partial translations available in
  <table>
    <tr><td><a href="/book/cs">Čeština</a>,</td></tr>
    <tr><td><a href="/book/mk">Македонски</a>,</td></tr>
    <tr><td><a href="/book/pl">Polski</a>,</td></tr>
    <tr><td><a href="/book/sr">Српски</a>,</td></tr>
    <tr><td><a href="/book/uz">Ўзбекча</a>,</td></tr>
    <tr><td><a href="/book/zh-tw">繁體中文</a>,</td></tr>
  </table>
</p>
<p>
  Translations started for
  <table>
    <tr><td><a href="/book/be">Беларуская</a>,</td></tr>
    <tr><td><a href="/book/fa" dir="rtl">فارسی</a>,</td></tr>
    <tr><td><a href="/book/id">Indonesian</a>,</td></tr>
    <tr><td><a href="/book/it">Italiano</a>,</td></tr>
    <tr><td><a href="/book/ms">Bahasa Melayu</a>,</td></tr>
    <tr><td><a href="/book/pt-br">Português (Brasil)</a>,</td></tr>
    <tr><td><a href="/book/pt-pt">Português (Portugal)</a>,</td></tr>
    <tr><td><a href="/book/sv">Svenska</a>,</td></tr>
    <tr><td><a href="/book/tr">Türkçe</a>.</td></tr>
  </table>
</p>
<hr class="sidebar"/>
<p>
The source of this book is  <a href="https://github.com/progit/progit2-zh">hosted on GitHub.</a></br>
Patches, suggestions and comments are welcome.
</p>


  </nav>
</aside>

        <div id="content">
          

<div id='book-chapters'>
  <a class="dropdown-trigger" id="book-chapters-trigger" data-panel-id="chapters-dropdown" href="#">Chapters ▾</a>
<div class='dropdown-panel' id='chapters-dropdown'>
  <div class="three-column">
    <div class='column-left'>
      <ol class='book-toc'>
  <li class='chapter'>
  <h2>1. <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%85%B3%E4%BA%8E%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6">起步</a></h2>
    <ol>
        <li>
          1.1
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%85%B3%E4%BA%8E%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6" >关于版本控制 </a>
        </li>
        <li>
          1.2
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-Git-%E7%AE%80%E5%8F%B2" >Git 简史 </a>
        </li>
        <li>
          1.3
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-Git-%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F" >Git 是什么？ </a>
        </li>
        <li>
          1.4
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%91%BD%E4%BB%A4%E8%A1%8C" >命令行 </a>
        </li>
        <li>
          1.5
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git" >安装 Git </a>
        </li>
        <li>
          1.6
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%88%9D%E6%AC%A1%E8%BF%90%E8%A1%8C-Git-%E5%89%8D%E7%9A%84%E9%85%8D%E7%BD%AE" >初次运行 Git 前的配置 </a>
        </li>
        <li>
          1.7
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E8%8E%B7%E5%8F%96%E5%B8%AE%E5%8A%A9" >获取帮助 </a>
        </li>
        <li>
          1.8
          <a href="/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>2. <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%8E%B7%E5%8F%96-Git-%E4%BB%93%E5%BA%93">Git 基础</a></h2>
    <ol>
        <li>
          2.1
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%8E%B7%E5%8F%96-Git-%E4%BB%93%E5%BA%93" >获取 Git 仓库 </a>
        </li>
        <li>
          2.2
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%AE%B0%E5%BD%95%E6%AF%8F%E6%AC%A1%E6%9B%B4%E6%96%B0%E5%88%B0%E4%BB%93%E5%BA%93" >记录每次更新到仓库 </a>
        </li>
        <li>
          2.3
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%9F%A5%E7%9C%8B%E6%8F%90%E4%BA%A4%E5%8E%86%E5%8F%B2" >查看提交历史 </a>
        </li>
        <li>
          2.4
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%92%A4%E6%B6%88%E6%93%8D%E4%BD%9C" >撤消操作 </a>
        </li>
        <li>
          2.5
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E8%BF%9C%E7%A8%8B%E4%BB%93%E5%BA%93%E7%9A%84%E4%BD%BF%E7%94%A8" >远程仓库的使用 </a>
        </li>
        <li>
          2.6
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%89%93%E6%A0%87%E7%AD%BE" >打标签 </a>
        </li>
        <li>
          2.7
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-Git-%E5%88%AB%E5%90%8D" >Git 别名 </a>
        </li>
        <li>
          2.8
          <a href="/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>3. <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%80%E4%BB%8B">Git 分支</a></h2>
    <ol>
        <li>
          3.1
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%80%E4%BB%8B" >分支简介 </a>
        </li>
        <li>
          3.2
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%9A%84%E6%96%B0%E5%BB%BA%E4%B8%8E%E5%90%88%E5%B9%B6" >分支的新建与合并 </a>
        </li>
        <li>
          3.3
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E7%AE%A1%E7%90%86" >分支管理 </a>
        </li>
        <li>
          3.4
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%88%86%E6%94%AF%E5%BC%80%E5%8F%91%E5%B7%A5%E4%BD%9C%E6%B5%81" >分支开发工作流 </a>
        </li>
        <li>
          3.5
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E8%BF%9C%E7%A8%8B%E5%88%86%E6%94%AF" >远程分支 </a>
        </li>
        <li>
          3.6
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%8F%98%E5%9F%BA" >变基 </a>
        </li>
        <li>
          3.7
          <a href="/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>4. <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E5%8D%8F%E8%AE%AE">服务器上的 Git</a></h2>
    <ol>
        <li>
          4.1
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E5%8D%8F%E8%AE%AE" >协议 </a>
        </li>
        <li>
          4.2
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E5%9C%A8%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E6%90%AD%E5%BB%BA-Git" >在服务器上搭建 Git </a>
        </li>
        <li>
          4.3
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E7%94%9F%E6%88%90-SSH-%E5%85%AC%E9%92%A5" >生成 SSH 公钥 </a>
        </li>
        <li>
          4.4
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E9%85%8D%E7%BD%AE%E6%9C%8D%E5%8A%A1%E5%99%A8" >配置服务器 </a>
        </li>
        <li>
          4.5
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-Git-%E5%AE%88%E6%8A%A4%E8%BF%9B%E7%A8%8B" >Git 守护进程 </a>
        </li>
        <li>
          4.6
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-Smart-HTTP" >Smart HTTP </a>
        </li>
        <li>
          4.7
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-GitWeb" >GitWeb </a>
        </li>
        <li>
          4.8
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-GitLab" >GitLab </a>
        </li>
        <li>
          4.9
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E7%AC%AC%E4%B8%89%E6%96%B9%E6%89%98%E7%AE%A1%E7%9A%84%E9%80%89%E6%8B%A9" >第三方托管的选择 </a>
        </li>
        <li>
          4.10
          <a href="/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>5. <a href="/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E5%88%86%E5%B8%83%E5%BC%8F%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B">分布式 Git</a></h2>
    <ol>
        <li>
          5.1
          <a href="/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E5%88%86%E5%B8%83%E5%BC%8F%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B" >分布式工作流程 </a>
        </li>
        <li>
          5.2
          <a href="/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E5%90%91%E4%B8%80%E4%B8%AA%E9%A1%B9%E7%9B%AE%E8%B4%A1%E7%8C%AE" >向一个项目贡献 </a>
        </li>
        <li>
          5.3
          <a href="/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E7%BB%B4%E6%8A%A4%E9%A1%B9%E7%9B%AE" >维护项目 </a>
        </li>
        <li>
          5.4
          <a href="/book/zh/v2/%E5%88%86%E5%B8%83%E5%BC%8F-Git-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
</ol>

    </div>
    <div class='column-middle'>
      <ol class='book-toc'>
  <li class='chapter'>
  <h2>6. <a href="/book/zh/v2/GitHub-%E8%B4%A6%E6%88%B7%E7%9A%84%E5%88%9B%E5%BB%BA%E5%92%8C%E9%85%8D%E7%BD%AE">GitHub</a></h2>
    <ol>
        <li>
          6.1
          <a href="/book/zh/v2/GitHub-%E8%B4%A6%E6%88%B7%E7%9A%84%E5%88%9B%E5%BB%BA%E5%92%8C%E9%85%8D%E7%BD%AE" >账户的创建和配置 </a>
        </li>
        <li>
          6.2
          <a href="/book/zh/v2/GitHub-%E5%AF%B9%E9%A1%B9%E7%9B%AE%E5%81%9A%E5%87%BA%E8%B4%A1%E7%8C%AE" >对项目做出贡献 </a>
        </li>
        <li>
          6.3
          <a href="/book/zh/v2/GitHub-%E7%BB%B4%E6%8A%A4%E9%A1%B9%E7%9B%AE" >维护项目 </a>
        </li>
        <li>
          6.4
          <a href="/book/zh/v2/GitHub-%E7%AE%A1%E7%90%86%E7%BB%84%E7%BB%87" >管理组织 </a>
        </li>
        <li>
          6.5
          <a href="/book/zh/v2/GitHub-%E8%84%9A%E6%9C%AC-GitHub" >脚本 GitHub </a>
        </li>
        <li>
          6.6
          <a href="/book/zh/v2/GitHub-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>7. <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%80%89%E6%8B%A9%E4%BF%AE%E8%AE%A2%E7%89%88%E6%9C%AC">Git 工具</a></h2>
    <ol>
        <li>
          7.1
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%80%89%E6%8B%A9%E4%BF%AE%E8%AE%A2%E7%89%88%E6%9C%AC" >选择修订版本 </a>
        </li>
        <li>
          7.2
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E4%BA%A4%E4%BA%92%E5%BC%8F%E6%9A%82%E5%AD%98" >交互式暂存 </a>
        </li>
        <li>
          7.3
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E8%B4%AE%E8%97%8F%E4%B8%8E%E6%B8%85%E7%90%86" >贮藏与清理 </a>
        </li>
        <li>
          7.4
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E7%AD%BE%E7%BD%B2%E5%B7%A5%E4%BD%9C" >签署工作 </a>
        </li>
        <li>
          7.5
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E6%90%9C%E7%B4%A2" >搜索 </a>
        </li>
        <li>
          7.6
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%87%8D%E5%86%99%E5%8E%86%E5%8F%B2" >重写历史 </a>
        </li>
        <li>
          7.7
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%87%8D%E7%BD%AE%E6%8F%AD%E5%AF%86" >重置揭密 </a>
        </li>
        <li>
          7.8
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%AB%98%E7%BA%A7%E5%90%88%E5%B9%B6" >高级合并 </a>
        </li>
        <li>
          7.9
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-Rerere" >Rerere </a>
        </li>
        <li>
          7.10
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E4%BD%BF%E7%94%A8-Git-%E8%B0%83%E8%AF%95" >使用 Git 调试 </a>
        </li>
        <li>
          7.11
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E5%AD%90%E6%A8%A1%E5%9D%97" >子模块 </a>
        </li>
        <li>
          7.12
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E6%89%93%E5%8C%85" >打包 </a>
        </li>
        <li>
          7.13
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E6%9B%BF%E6%8D%A2" >替换 </a>
        </li>
        <li>
          7.14
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E5%87%AD%E8%AF%81%E5%AD%98%E5%82%A8" >凭证存储 </a>
        </li>
        <li>
          7.15
          <a href="/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>8. <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E9%85%8D%E7%BD%AE-Git">自定义 Git</a></h2>
    <ol>
        <li>
          8.1
          <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E9%85%8D%E7%BD%AE-Git" >配置 Git </a>
        </li>
        <li>
          8.2
          <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E5%B1%9E%E6%80%A7" class=active>Git 属性 </a>
        </li>
        <li>
          8.3
          <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E9%92%A9%E5%AD%90" >Git 钩子 </a>
        </li>
        <li>
          8.4
          <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E4%BD%BF%E7%94%A8%E5%BC%BA%E5%88%B6%E7%AD%96%E7%95%A5%E7%9A%84%E4%B8%80%E4%B8%AA%E4%BE%8B%E5%AD%90" >使用强制策略的一个例子 </a>
        </li>
        <li>
          8.5
          <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>9. <a href="/book/zh/v2/Git-%E4%B8%8E%E5%85%B6%E4%BB%96%E7%B3%BB%E7%BB%9F-%E4%BD%9C%E4%B8%BA%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%9A%84-Git">Git 与其他系统</a></h2>
    <ol>
        <li>
          9.1
          <a href="/book/zh/v2/Git-%E4%B8%8E%E5%85%B6%E4%BB%96%E7%B3%BB%E7%BB%9F-%E4%BD%9C%E4%B8%BA%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%9A%84-Git" >作为客户端的 Git </a>
        </li>
        <li>
          9.2
          <a href="/book/zh/v2/Git-%E4%B8%8E%E5%85%B6%E4%BB%96%E7%B3%BB%E7%BB%9F-%E8%BF%81%E7%A7%BB%E5%88%B0-Git" >迁移到 Git </a>
        </li>
        <li>
          9.3
          <a href="/book/zh/v2/Git-%E4%B8%8E%E5%85%B6%E4%BB%96%E7%B3%BB%E7%BB%9F-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>10. <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E5%BA%95%E5%B1%82%E5%91%BD%E4%BB%A4%E4%B8%8E%E4%B8%8A%E5%B1%82%E5%91%BD%E4%BB%A4">Git 内部原理</a></h2>
    <ol>
        <li>
          10.1
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E5%BA%95%E5%B1%82%E5%91%BD%E4%BB%A4%E4%B8%8E%E4%B8%8A%E5%B1%82%E5%91%BD%E4%BB%A4" >底层命令与上层命令 </a>
        </li>
        <li>
          10.2
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-Git-%E5%AF%B9%E8%B1%A1" >Git 对象 </a>
        </li>
        <li>
          10.3
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-Git-%E5%BC%95%E7%94%A8" >Git 引用 </a>
        </li>
        <li>
          10.4
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E5%8C%85%E6%96%87%E4%BB%B6" >包文件 </a>
        </li>
        <li>
          10.5
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E5%BC%95%E7%94%A8%E8%A7%84%E8%8C%83" >引用规范 </a>
        </li>
        <li>
          10.6
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE" >传输协议 </a>
        </li>
        <li>
          10.7
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E7%BB%B4%E6%8A%A4%E4%B8%8E%E6%95%B0%E6%8D%AE%E6%81%A2%E5%A4%8D" >维护与数据恢复 </a>
        </li>
        <li>
          10.8
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F" >环境变量 </a>
        </li>
        <li>
          10.9
          <a href="/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
</ol>

    </div>
    <div class='column-right'>
      <ol class='book-toc'>
  <li class='chapter'>
  <h2>A1. <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-%E5%9B%BE%E5%BD%A2%E7%95%8C%E9%9D%A2">附录 A: 在其它环境中使用 Git</a></h2>
    <ol>
        <li>
          A1.1
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-%E5%9B%BE%E5%BD%A2%E7%95%8C%E9%9D%A2" >图形界面 </a>
        </li>
        <li>
          A1.2
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Visual-Studio-%E4%B8%AD%E7%9A%84-Git" >Visual Studio 中的 Git </a>
        </li>
        <li>
          A1.3
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Visual-Studio-Code-%E4%B8%AD%E7%9A%84-Git" >Visual Studio Code 中的 Git </a>
        </li>
        <li>
          A1.4
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Eclipse-%E4%B8%AD%E7%9A%84-Git" >Eclipse 中的 Git </a>
        </li>
        <li>
          A1.5
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-IntelliJ-%2F-PyCharm-%2F-WebStorm-%2F-PhpStorm-%2F-RubyMine-%E4%B8%AD%E7%9A%84-Git" >IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中的 Git </a>
        </li>
        <li>
          A1.6
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Sublime-Text-%E4%B8%AD%E7%9A%84-Git" >Sublime Text 中的 Git </a>
        </li>
        <li>
          A1.7
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Bash-%E4%B8%AD%E7%9A%84-Git" >Bash 中的 Git </a>
        </li>
        <li>
          A1.8
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Zsh-%E4%B8%AD%E7%9A%84-Git" >Zsh 中的 Git </a>
        </li>
        <li>
          A1.9
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-Git-%E5%9C%A8-PowerShell-%E4%B8%AD%E4%BD%BF%E7%94%A8-Git" >Git 在 PowerShell 中使用 Git </a>
        </li>
        <li>
          A1.10
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-A%3A-%E5%9C%A8%E5%85%B6%E5%AE%83%E7%8E%AF%E5%A2%83%E4%B8%AD%E4%BD%BF%E7%94%A8-Git-%E6%80%BB%E7%BB%93" >总结 </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>A2. <a href="/book/zh/v2/%E9%99%84%E5%BD%95-B%3A-%E5%9C%A8%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E5%B5%8C%E5%85%A5-Git-%E5%91%BD%E4%BB%A4%E8%A1%8C-Git-%E6%96%B9%E5%BC%8F">附录 B: 在你的应用中嵌入 Git</a></h2>
    <ol>
        <li>
          A2.1
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-B%3A-%E5%9C%A8%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E5%B5%8C%E5%85%A5-Git-%E5%91%BD%E4%BB%A4%E8%A1%8C-Git-%E6%96%B9%E5%BC%8F" >命令行 Git 方式 </a>
        </li>
        <li>
          A2.2
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-B%3A-%E5%9C%A8%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E5%B5%8C%E5%85%A5-Git-Libgit2" >Libgit2 </a>
        </li>
        <li>
          A2.3
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-B%3A-%E5%9C%A8%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E5%B5%8C%E5%85%A5-Git-JGit" >JGit </a>
        </li>
        <li>
          A2.4
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-B%3A-%E5%9C%A8%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E5%B5%8C%E5%85%A5-Git-go-git" >go-git </a>
        </li>
        <li>
          A2.5
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-B%3A-%E5%9C%A8%E4%BD%A0%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E5%B5%8C%E5%85%A5-Git-Dulwich" >Dulwich </a>
        </li>
    </ol>
  </li>
  <li class='chapter'>
  <h2>A3. <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E8%AE%BE%E7%BD%AE%E4%B8%8E%E9%85%8D%E7%BD%AE">附录 C: Git 命令</a></h2>
    <ol>
        <li>
          A3.1
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E8%AE%BE%E7%BD%AE%E4%B8%8E%E9%85%8D%E7%BD%AE" >设置与配置 </a>
        </li>
        <li>
          A3.2
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E8%8E%B7%E5%8F%96%E4%B8%8E%E5%88%9B%E5%BB%BA%E9%A1%B9%E7%9B%AE" >获取与创建项目 </a>
        </li>
        <li>
          A3.3
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E5%BF%AB%E7%85%A7%E5%9F%BA%E7%A1%80" >快照基础 </a>
        </li>
        <li>
          A3.4
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E5%88%86%E6%94%AF%E4%B8%8E%E5%90%88%E5%B9%B6" >分支与合并 </a>
        </li>
        <li>
          A3.5
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E9%A1%B9%E7%9B%AE%E5%88%86%E4%BA%AB%E4%B8%8E%E6%9B%B4%E6%96%B0" >项目分享与更新 </a>
        </li>
        <li>
          A3.6
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E6%A3%80%E6%9F%A5%E4%B8%8E%E6%AF%94%E8%BE%83" >检查与比较 </a>
        </li>
        <li>
          A3.7
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E8%B0%83%E8%AF%95" >调试 </a>
        </li>
        <li>
          A3.8
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E8%A1%A5%E4%B8%81" >补丁 </a>
        </li>
        <li>
          A3.9
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E9%82%AE%E4%BB%B6" >邮件 </a>
        </li>
        <li>
          A3.10
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E5%A4%96%E9%83%A8%E7%B3%BB%E7%BB%9F" >外部系统 </a>
        </li>
        <li>
          A3.11
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E7%AE%A1%E7%90%86" >管理 </a>
        </li>
        <li>
          A3.12
          <a href="/book/zh/v2/%E9%99%84%E5%BD%95-C%3A-Git-%E5%91%BD%E4%BB%A4-%E5%BA%95%E5%B1%82%E5%91%BD%E4%BB%A4" >底层命令 </a>
        </li>
    </ol>
  </li>
</ol>

    </div>
  </div>
 </div>

    <span class="light" id="edition">
      2nd Edition
    </span>
</div>

<div id='main' class="book edition2">
    <h1>8.2 自定义 Git - Git 属性</h1>
  <div>
<h2 id="_git_属性">Git 属性</h2>
<div class="paragraph">
<p>
你也可以针对特定的路径配置某些设置项，这样 Git 就只对特定的子目录或子文件集运用它们。
这些基于路径的设置项被称为 Git 属性，可以在你的目录下的 <code>.gitattributes</code> 文件内进行设置（通常是你的项目的根目录）。如果不想让这些属性文件与其它文件一同提交，你也可以在 <code>.git/info/attributes</code> 文件中进行设置。</p>
</div>
<div class="paragraph">
<p>通过使用属性，你可以对项目中的文件或目录单独定义不同的合并策略，让 Git 知道怎样比较非文本文件，或者让 Git 在提交或检出前过滤内容。
在本节，你将学习到一些能在自己的项目中用到的属性，并看到几个实际的例子。</p>
</div>
<div class="sect3">
<h3 id="_二进制文件">二进制文件</h3>
<div class="paragraph">
<p>
你可以用 Git 属性让 Git 知道哪些是二进制文件（以防它没有识别出来），并指示其如何处理这些文件。
例如，一些文本文件是由机器产生的，没有办法进行比较，但是一些二进制文件可以比较。
你将了解到怎样让 Git 区分这些文件。</p>
</div>
<div class="sect4">
<h4 id="_识别二进制文件">识别二进制文件</h4>
<div class="paragraph">
<p>有些文件表面上是文本文件，实质上应被作为二进制文件处理。
例如，macOS 平台上的 Xcode 项目会包含一个以 <code>.pbxproj</code> 结尾的文件，
它通常是一个记录项目构建配置等信息的 JSON（纯文本 Javascript 数据类型）数据集，由 IDE 写入磁盘。
虽然技术上看它是由 UTF-8 编码的文本文件，但你并不会希望将它当作文本文件来处理，
因为它其实是一个轻量级数据库——如果有两个人修改了它，你通常无法合并内容，diff 的输出也帮不上什么忙。
它本应被机器处理。因此，你想把它当成二进制文件。</p>
</div>
<div class="paragraph">
<p>要让 Git 把所有 <code>pbxproj</code> 文件当成二进制文件，在 <code>.gitattributes</code> 文件中如下设置：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">*.pbxproj binary</code></pre>
</div>
</div>
<div class="paragraph">
<p>现在，Git 不会尝试转换或修正回车换行（CRLF）问题，当你在项目中运行 <code>git show</code> 或 <code>git diff</code> 时，Git 也不会比较或打印该文件的变化。</p>
</div>
</div>
<div class="sect4">
<h4 id="_比较二进制文件">比较二进制文件</h4>
<div class="paragraph">
<p>你也可以使用 Git 属性来有效地比较两个二进制文件。
秘诀在于，告诉 Git 怎么把你的二进制文件转化为文本格式，从而能够使用普通的 diff 方式进行对比。</p>
</div>
<div class="paragraph">
<p>首先，让我们尝试用这个技术解决世人最头疼的问题之一：对 Microsoft Word 文档进行版本控制。
大家都知道，Microsoft Word 几乎是世上最难缠的编辑器，尽管如此，大家还是在用它。
如果想对 Word 文档进行版本控制，你可以把文件加入到 Git 库中，每次修改后提交即可。但这样做有什么实际意义呢？
毕竟运行 <code>git diff</code> 命令后，你只能得到如下的结果：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git diff
diff --git a/chapter1.docx b/chapter1.docx
index 88839c4..4afcb7c 100644
Binary files a/chapter1.docx and b/chapter1.docx differ</code></pre>
</div>
</div>
<div class="paragraph">
<p>除了检出之后睁大眼睛逐行扫描，就真的没有办法直接比较两个不同版本的 Word 文档吗？
Git 属性能很好地解决此问题。
把下面这行文本加到你的 <code>.gitattributes</code> 文件中：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">*.docx diff=word</code></pre>
</div>
</div>
<div class="paragraph">
<p>这告诉 Git 当你尝试查看包含变更的比较结果时，所有匹配 <code>.docx</code> 模式的文件都应该使用“word”过滤器。
“word”过滤器是什么？
我们现在就来设置它。
我们会对 Git 进行配置，令其能够借助 <code>docx2txt</code> 程序将 Word 文档转为可读文本文件，这样不同的文件间就能够正确比较了。</p>
</div>
<div class="paragraph">
<p>首先，你需要安装 <code>docx2txt</code>；它可以从 <a href="https://sourceforge.net/projects/docx2txt" class="bare">https://sourceforge.net/projects/docx2txt</a> 下载。
按照 <code>INSTALL</code> 文件的说明，把它放到你的可执行路径下。
接下来，你还需要写一个脚本把输出结果包装成 Git 支持的格式。
在你的可执行路径下创建一个叫 <code>docx2txt</code> 文件，添加这些内容：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">#!/bin/bash
docx2txt.pl "$1" -</code></pre>
</div>
</div>
<div class="paragraph">
<p>别忘了用 <code>chmod a+x</code> 给这个文件加上可执行权限。
最后，你需要配置 Git 来使用这个脚本：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git config diff.word.textconv docx2txt</code></pre>
</div>
</div>
<div class="paragraph">
<p>现在如果在两个快照之间进行比较，Git 就会对那些以 <code>.docx</code> 结尾的文件应用“word”过滤器，即 <code>docx2txt</code>。
这样你的 Word 文件就能被高效地转换成文本文件并进行比较了。</p>
</div>
<div class="paragraph">
<p>作为例子，我把本书的第一章另存为 Word 文件，并提交到 Git 版本库。
接着，往其中加入一个新的段落。
运行 <code>git diff</code>，输出如下：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git diff
diff --git a/chapter1.docx b/chapter1.docx
index 0b013ca..ba25db5 100644
--- a/chapter1.docx
+++ b/chapter1.docx
@@ -2,6 +2,7 @@
 This chapter will be about getting started with Git. We will begin at the beginning by explaining some background on version control tools, then move on to how to get Git running on your system and finally how to get it setup to start working with. At the end of this chapter you should understand why Git is around, why you should use it and you should be all setup to do so.
 1.1. About Version Control
 What is "version control", and why should you care? Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. For the examples in this book you will use software source code as the files being version controlled, though in reality you can do this with nearly any type of file on a computer.
+Testing: 1, 2, 3.
 If you are a graphic or web designer and want to keep every version of an image or layout (which you would most certainly want to), a Version Control System (VCS) is a very wise thing to use. It allows you to revert files back to a previous state, revert the entire project back to a previous state, compare changes over time, see who last modified something that might be causing a problem, who introduced an issue and when, and more. Using a VCS also generally means that if you screw things up or lose files, you can easily recover. In addition, you get all this for very little overhead.
 1.1.1. Local Version Control Systems
 Many people's version-control method of choice is to copy files into another directory (perhaps a time-stamped directory, if they're clever). This approach is very common because it is so simple, but it is also incredibly error prone. It is easy to forget which directory you're in and accidentally write to the wrong file or copy over files you don't mean to.</code></pre>
</div>
</div>
<div class="paragraph">
<p>Git 成功地挑出了我们添加的那句话“Testing: 1, 2, 3.”，一字不差。
还算不上完美——格式上的变动显示不出来——但已经足够了。</p>
</div>
<div class="paragraph">
<p>你还能用这个方法比较图像文件。
其中一个办法是，在比较时对图像文件运用一个过滤器，提炼出 EXIF 信息——这是在大部分图像格式中都有记录的一种元数据。
如果你下载并安装了 <code>exiftool</code> 程序，可以利用它将图像转换为关于元数据的文本信息，这样比较时至少能以文本的形式显示发生过的变动：
将以下内容放到你的 <code>.gitattributes</code> 文件中：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">*.png diff=exif</code></pre>
</div>
</div>
<div class="paragraph">
<p>配置 Git 以使用此工具：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git config diff.exif.textconv exiftool</code></pre>
</div>
</div>
<div class="paragraph">
<p>如果在项目中替换了一个图像文件，运行 <code>git diff</code> 命令的结果如下：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-diff" data-lang="diff">diff --git a/image.png b/image.png
index 88839c4..4afcb7c 100644
--- a/image.png
+++ b/image.png
@@ -1,12 +1,12 @@
 ExifTool Version Number         : 7.74
-File Size                       : 70 kB
-File Modification Date/Time     : 2009:04:21 07:02:45-07:00
+File Size                       : 94 kB
+File Modification Date/Time     : 2009:04:21 07:02:43-07:00
 File Type                       : PNG
 MIME Type                       : image/png
-Image Width                     : 1058
-Image Height                    : 889
+Image Width                     : 1056
+Image Height                    : 827
 Bit Depth                       : 8
 Color Type                      : RGB with Alpha</code></pre>
</div>
</div>
<div class="paragraph">
<p>你一眼就能看出文件大小和图像尺寸发生了变化。</p>
</div>
</div>
</div>
<div class="sect3">
<h3 id="_keyword_expansion">关键字展开</h3>
<div class="paragraph">
<p>
SVN 或 CVS 风格的关键字展开（keyword expansion）功能经常会被习惯于上述系统的开发者使用到。
在 Git 中，这项功能有一个主要问题，就是你无法利用它往文件中加入其关联提交的相关信息，因为 Git 总是先对文件做校验和运算（译者注：Git 中提交对象的校验依赖于文件的校验和，而 Git 属性针对特定文件或路径，因此基于 Git 属性的关键字展开无法仅根据文件反推出对应的提交）。
不过，我们可以在检出某个文件后对其注入文本，并在再次提交前删除这些文本。
Git 属性提供了两种方法来达到这一目的。</p>
</div>
<div class="paragraph">
<p>一种方法是，你可以把文件所对应数据对象的 SHA-1 校验和自动注入到文件中的 <code>$Id$</code> 字段。
如果在一个或多个文件上设置了该属性，下次当你检出相关分支的时候，Git 会用相应数据对象的 SHA-1 值替换上述字段。
注意，这不是提交对象的 SHA-1 校验和，而是数据对象本身的校验和。
将以下内容放到你的 <code>.gitattributes</code> 文件中：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">*.txt ident</code></pre>
</div>
</div>
<div class="paragraph">
<p>在一个测试文件中添加一个 <code>$Id$</code> 引用：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ echo '$Id$' &gt; test.txt</code></pre>
</div>
</div>
<div class="paragraph">
<p>当你下次检出文件时，Git 将注入数据对象的 SHA-1 校验和：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ rm test.txt
$ git checkout -- test.txt
$ cat test.txt
$Id: 42812b7653c7b88933f8a9d6cad0ca16714b9bb3 $</code></pre>
</div>
</div>
<div class="paragraph">
<p>然而，这个结果的用途比较有限。
如果用过 CVS 或 Subversion 的关键字替换功能，我们会想加上一个时间戳信息——光有 SHA-1 校验和用途不大，
它仅仅是个随机字符串，你无法凭字面值来区分不同 SHA-1 时间上的先后。</p>
</div>
<div class="paragraph">
<p>因此 Git 属性提供了另一种方法：我们可以编写自己的过滤器来实现文件提交或检出时的关键字替换。
一个过滤器由“clean”和“smudge”两个子过滤器组成。
在 <code>.gitattributes</code> 文件中，你能对特定的路径设置一个过滤器，然后设置文件检出前的处理脚本（“smudge”，见 <a href="ch00/filters_a">“smudge”过滤器会在文件被检出时触发</a>）和文件暂存前的处理脚本（“clean”，见 <a href="ch00/filters_b">“clean”过滤器会在文件被暂存时触发</a>）。
这两个过滤器能够被用来做各种有趣的事。</p>
</div>
<div id="filters_a" class="imageblock">
<div class="content">
<img src="/book/en/v2/images/smudge.png" alt="“smudge”过滤器会在文件被检出时触发。">
</div>
<div class="title">Figure 144. “smudge”过滤器会在文件被检出时触发</div>
</div>
<div id="filters_b" class="imageblock">
<div class="content">
<img src="/book/en/v2/images/clean.png" alt="“clean”过滤器会在文件被暂存时触发。">
</div>
<div class="title">Figure 145. “clean”过滤器会在文件被暂存时触发</div>
</div>
<div class="paragraph">
<p>在（Git 源码中）实现这个特性的原始提交信息里给出了一个简单的例子：在提交前，用 <code>indent</code> 程序过滤所有 C 源码。
你可以在 <code>.gitattributes</code> 文件中对 filter 属性设置“indent”过滤器来过滤 <code>*.c</code> 文件</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">*.c filter=indent</code></pre>
</div>
</div>
<div class="paragraph">
<p>然后，通过以下配置，让 Git 知道“indent”过滤器在 smudge 和 clean 时分别该做什么：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git config --global filter.indent.clean indent
$ git config --global filter.indent.smudge cat</code></pre>
</div>
</div>
<div class="paragraph">
<p>在这个例子中，当你暂存 <code>*.c</code> 文件时，<code>indent</code> 程序会先被触发；在把它们检出回硬盘时，<code>cat</code> 程序会先被触发。
<code>cat</code> 在这里没什么实际作用：它仅仅把输入的数据重新输出。
这样的组合可以有效地在暂存前用 <code>indent</code> 过滤所有的 C 源码。</p>
</div>
<div class="paragraph">
<p>另一个有趣的例子是实现 RCS 风格的 <code>$Date$</code> 关键字展开。
要想演示这个例子，我们需要实现这样的一个小脚本：接受文件名参数，得到项目的最新提交日期，并把日期写入该文件。
下面是一个实现了该功能的 Ruby 小脚本：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ruby" data-lang="ruby">#! /usr/bin/env ruby
data = STDIN.read
last_date = `git log --pretty=format:"%ad" -1`
puts data.gsub('$Date$', '$Date: ' + last_date.to_s + '$')</code></pre>
</div>
</div>
<div class="paragraph">
<p>这个脚本从 <code>git log</code> 中得到最新提交日期，将其注入所有输入文件的 <code>$Date$</code> 字段，并输出结果——你可以使用最顺手的语言轻松实现一个类似的脚本。
把该脚本命名为 <code>expand_date</code>，放到你的可执行路径中。
现在，你需要在 Git 中设置一个过滤器（就叫它 <code>dater</code> 吧），让它在检出文件时调用你的 <code>expand_date</code> 来注入时间戳，完成 smudge 操作。
暂存文件时的 clean 操作则是用一行 Perl 表达式清除注入的内容：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git config filter.dater.smudge expand_date
$ git config filter.dater.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'</code></pre>
</div>
</div>
<div class="paragraph">
<p>这段 Perl 代码会删除 <code>$Date$</code> 后面注入的内容，恢复它的原貌。
过滤器终于准备完成了，是时候测试一下。创建一个带有 <code>$Date$</code> 关键字的文件，
然后给它设置一个 Git 属性，关联我们的新过滤器：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">date*.txt filter=dater</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ echo '# $Date$' &gt; date_test.txt</code></pre>
</div>
</div>
<div class="paragraph">
<p>提交该文件，并再次检出，你会发现关键字如期被替换了：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git add date_test.txt .gitattributes
$ git commit -m "Testing date expansion in Git"
$ rm date_test.txt
$ git checkout date_test.txt
$ cat date_test.txt
# $Date: Tue Apr 21 07:26:52 2009 -0700$</code></pre>
</div>
</div>
<div class="paragraph">
<p>自定义过滤器真的很强大。
不过你需要注意的是，因为 <code>.gitattributes</code> 文件会随着项目一起提交，而过滤器（例如这里的 <code>dater</code>）不会，所以过滤器有可能会失效。
当你在设计这些过滤器时，要注重容错性——它们在出错时应该能优雅地退出，从而不至于影响项目的正常运行。</p>
</div>
</div>
<div class="sect3">
<h3 id="_导出版本库">导出版本库</h3>
<div class="paragraph">
<p>
Git 属性在导出项目归档（archive）时也能发挥作用。</p>
</div>
<div class="sect4">
<h4 id="_export_ignore"><code>export-ignore</code></h4>
<div class="paragraph">
<p>当归档的时候，可以设置 Git 不导出某些文件和目录。
如果你不想在归档中包含某个子目录或文件，但想把它们纳入项目的版本管理中，你可以在 <code>export-ignore</code> 属性中指定它们。</p>
</div>
<div class="paragraph">
<p>例如，假设你在 <code>test/</code> 子目录下有一些测试文件，不希望它们被包含在项目导出的压缩包（tarball）中。
你可以增加下面这行到 Git 属性文件中：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">test/ export-ignore</code></pre>
</div>
</div>
<div class="paragraph">
<p>现在，当你运行 <code>git archive</code> 来创建项目的压缩包时，那个目录不会被包括在归档中。</p>
</div>
</div>
<div class="sect4">
<h4 id="_export_subst"><code>export-subst</code></h4>
<div class="paragraph">
<p>在导出文件进行部署的时候，你可以将 <code>git log</code> 的格式化和关键字展开处理应用到标记了
<code>export-subst</code> 属性的部分文件。</p>
</div>
<div class="paragraph">
<p>举个例子，如果你想在项目中包含一个叫做 <code>LAST_COMMIT</code> 的文件，
并在运行 <code>git archive</code> 的时候自动向它注入最新提交的元数据，可以像这样设置
<code>.gitattributes</code> 和 <code>LAST_COMMIT</code> 该文件：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">LAST_COMMIT export-subst</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ echo 'Last commit date: $Format:%cd by %aN$' &gt; LAST_COMMIT
$ git add LAST_COMMIT .gitattributes
$ git commit -am 'adding LAST_COMMIT file for archives'</code></pre>
</div>
</div>
<div class="paragraph">
<p>运行 <code>git archive</code> 之后，归档文件的内容会被替换成这样：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git archive HEAD | tar xCf ../deployment-testing -
$ cat ../deployment-testing/LAST_COMMIT
Last commit date: Tue Apr 21 08:38:48 2009 -0700 by Scott Chacon</code></pre>
</div>
</div>
<div class="paragraph">
<p>你也可以用诸如提交信息或者任意的 <code>git notes</code> 进行替换，并且 <code>git log</code> 还能做简单的字词折行：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ echo '$Format:Last commit: %h by %aN at %cd%n%+w(76,6,9)%B$' &gt; LAST_COMMIT
$ git commit -am 'export-subst uses git log'\''s custom formatter

git archive 直接使用 git log 的 `pretty=format:`
处理器，并在输出中移除两侧的 `$Format:` 和 `$`
标记。
'
$ git archive @ | tar xfO - LAST_COMMIT
Last commit: 312ccc8 by Jim Hill at Fri May 8 09:14:04 2015 -0700
       export-subst uses git log's custom formatter

         git archive uses git log's `pretty=format:` processor directly, and
         strips the surrounding `$Format:` and `$` markup from the output.</code></pre>
</div>
</div>
<div class="paragraph">
<p>由此得到的归档适用于（当前的）部署工作。然而和其他的导出归档一样，它并不适用于后继的部署工作。</p>
</div>
</div>
</div>
<div class="sect3">
<h3 id="_合并策略">合并策略</h3>
<div class="paragraph">
<p>
通过 Git 属性，你还能对项目中的特定文件指定不同的合并策略。
一个非常有用的选项就是，告诉 Git 当特定文件发生冲突时不要尝试合并它们，而是直接使用你这边的内容。</p>
</div>
<div class="paragraph">
<p>考虑如下场景：项目中有一个分叉的或者定制过的主题分支，你希望该分支上的更改能合并回你的主干分支，同时需要忽略其中某些文件。此时这个合并策略就能派上用场。
假设你有一个数据库设置文件 <code>database.xml</code>，在两个分支中它是不同的，而你想合并另一个分支到你的分支上，又不想弄乱该数据库文件。
你可以设置属性如下：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ini" data-lang="ini">database.xml merge=ours</code></pre>
</div>
</div>
<div class="paragraph">
<p>然后定义一个虚拟的合并策略，叫做 <code>ours</code>：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git config --global merge.ours.driver true</code></pre>
</div>
</div>
<div class="paragraph">
<p>如果你合并了另一个分支，<code>database.xml</code> 文件不会有合并冲突，相反会显示如下信息：</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-console" data-lang="console">$ git merge topic
Auto-merging database.xml
Merge made by recursive.</code></pre>
</div>
</div>
<div class="paragraph">
<p>这里，<code>database.xml</code> 保持了主干分支中的原始版本。</p>
</div>
</div>
<div id="nav"><a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-%E9%85%8D%E7%BD%AE-Git">prev</a> | <a href="/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E9%92%A9%E5%AD%90">next</a></div></div>
</div>

        </div>
      </div>
      <footer>
  <div class="site-source">
    <a href="/site">About this site</a><br>
    Patches, suggestions, and comments are welcome.
  </div>
  <div class="sfc-member">
    Git is a member of <a href="/sfc">Software Freedom Conservancy</a>
  </div>
</footer>
<a href="#top" class="no-js scrollToTop" id="scrollToTop" data-label="Scroll to top">
  <img src="/images/icons/chevron-up@2x.png" width="20" height="20" alt="scroll-to-top"/>
</a>
<script src="/assets/application-b09f91f7c527919e4bc194769429065537d64a7f73b9fe93b107afef32b02939.js"></script>

    </div>

</body>
</html>
